﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Classes_and_Interfaces.SupportClasses;

namespace Classes_and_Interfaces.SupportClasses
{
	class StupensForHarmonyMaker
	{
        public static Note[] make(List<int> possibleStupens, Note ourNote, string raspologenie, int countOfVoices)
        {
            Note[] result = new Note[countOfVoices];

            result[Constants.BASS] = new Note(Constants.BASS, possibleStupens.ElementAt(Constants.BASS),null); //в басовый голос всегда вписываем ноту со ступенью, записанной в начале списка pS
            possibleStupens.RemoveAt(0); //удаляем исползованную ступень из списка возможных (чтобы не использовать ее повторно)
            result[ourNote.getVoice()] = ourNote; //далее вписываем в аккорд известную ноту ourNote (если она басовая, то она перезапишется)

            if (ourNote.getVoice() == Constants.BASS)
            {
                result[Constants.TENOR] = new Note(Constants.TENOR, possibleStupens.ElementAt((new Random()).Next(possibleStupens.Count)),null); //один из голосов (тенор) заполняем случайной ступенью
                
                if (raspologenie.Equals("тесное"))
                {
                    //в случае тесного расположения
                    for (int i = Constants.ALT, j = possibleStupens.IndexOf(ourNote.getStupen()) + 1; i < countOfVoices; i++, j++)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count],null);
                    }
                    //result[Constants.ALT] = new Note(Constants.ALT, possibleStupens[(possibleStupens.IndexOf(result[Constants.TENOR].getStupen()) + 1) % possibleStupens.Count]);
                    //result[Constants.SOPRANO] = new Note(Constants.SOPRANO, possibleStupens[(possibleStupens.IndexOf(result[Constants.TENOR].getStupen()) + 2) % possibleStupens.Count]);
                }
                else
                {
                    //в остальных случаях?
                    for (int i = Constants.ALT, j = possibleStupens.IndexOf(ourNote.getStupen()) + possibleStupens.Count - 1; i < countOfVoices; i++, j--)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count],null);
                    }
                    //result[Constants.ALT] = new Note(Constants.ALT, possibleStupens[(possibleStupens.IndexOf(result[Constants.TENOR].getStupen()) + 2) % possibleStupens.Count]);
                    //result[Constants.SOPRANO] = new Note(Constants.SOPRANO, possibleStupens[(possibleStupens.IndexOf(result[Constants.TENOR].getStupen()) + 1) % possibleStupens.Count]);
                }
            }
            else
            {
                if (raspologenie.Equals("тесное"))
                {
                    //в случае тесного расположения
                    for (int i = ourNote.getVoice() + 1, j = possibleStupens.IndexOf(ourNote.getStupen()) + 1; i < countOfVoices; i++,j++)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                    for (int i = ourNote.getVoice() - 1, j = possibleStupens.IndexOf(ourNote.getStupen()) + possibleStupens.Count - 1; i > 0; i--, j--)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                }
                else
                {
                    //в остальных случаях?
                    for (int i = ourNote.getVoice() + 1, j = possibleStupens.IndexOf(ourNote.getStupen()) + possibleStupens.Count - 1; i < countOfVoices; i++, j--)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                    for (int i = ourNote.getVoice() - 1, j = possibleStupens.IndexOf(ourNote.getStupen()) + 1; i > 0; i--, j++)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }   
                }
            }
            return result;            
        }
        public static Note[] make6(List<int> possibleStupens, Note ourNote, string raspologenie, int countOfVoices)
        {
            Note[] result = new Note[countOfVoices];

            result[Constants.BASS] = new Note(Constants.BASS, possibleStupens.ElementAt(Constants.BASS), null); //в басовый голос всегда вписываем ноту со ступенью, записанной в начале списка pS
            possibleStupens.RemoveAt(0); //удаляем исползованную ступень из списка возможных (чтобы не использовать ее повторно)
            result[ourNote.getVoice()] = ourNote; //далее вписываем в аккорд известную ноту ourNote (если она басовая, то она перезапишется)

            if (ourNote.getVoice() == Constants.BASS)
            {
                result[Constants.TENOR] = new Note(Constants.TENOR, possibleStupens.ElementAt((new Random()).Next(possibleStupens.Count)), null); //один из голосов (тенор) заполняем случайной ступенью
                
                if (raspologenie.Equals("тесное"))
                {
                    //в случае тесного расположения
                    for (int i = Constants.ALT, j = possibleStupens.IndexOf(ourNote.getStupen()) + 1; i < countOfVoices; i++, j++)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                    //result[Constants.ALT] = new Note(Constants.ALT, possibleStupens[(possibleStupens.IndexOf(result[Constants.TENOR].getStupen()) + 1) % possibleStupens.Count]);
                    //result[Constants.SOPRANO] = new Note(Constants.SOPRANO, possibleStupens[(possibleStupens.IndexOf(result[Constants.TENOR].getStupen()) + 2) % possibleStupens.Count]);
                }
                else
                {
                    //в остальных случаях?
                    for (int i = Constants.ALT, j = possibleStupens.IndexOf(ourNote.getStupen()) + possibleStupens.Count - 1; i < countOfVoices; i++, j--)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                    //result[Constants.ALT] = new Note(Constants.ALT, possibleStupens[(possibleStupens.IndexOf(result[Constants.TENOR].getStupen()) + 2) % possibleStupens.Count]);
                    //result[Constants.SOPRANO] = new Note(Constants.SOPRANO, possibleStupens[(possibleStupens.IndexOf(result[Constants.TENOR].getStupen()) + 1) % possibleStupens.Count]);
                }
            }
            else
            {
                if (raspologenie.Equals("тесное"))
                {
                    //в случае тесного расположения
                    for (int i = ourNote.getVoice() + 1, j = possibleStupens.IndexOf(ourNote.getStupen()) + 1; i < countOfVoices; i++, j++)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                    for (int i = ourNote.getVoice() - 1, j = possibleStupens.IndexOf(ourNote.getStupen()) + possibleStupens.Count - 1; i > 0; i--, j--)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                }
                else
                {
                    //в остальных случаях?
                    for (int i = ourNote.getVoice() + 1, j = possibleStupens.IndexOf(ourNote.getStupen()) + possibleStupens.Count - 1; i < countOfVoices; i++, j--)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                    for (int i = ourNote.getVoice() - 1, j = possibleStupens.IndexOf(ourNote.getStupen()) + 1; i > 0; i--, j++)
                    {
                        result[i] = new Note(i, possibleStupens[j % possibleStupens.Count], null);
                    }
                }
            }
            return result;   
        }
	}
}
